package com.zhiziai.aiproxy.config.security;


import com.zhiziai.aiproxy.exception.AdminLoginTokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.List;


public class JwtTokenUtils {
    private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtils.class);

    public static final String TOKEN_COOKIE = "authToken";
    public static final String TOKEN_PREFIX = "Bearer";

    private static final String SECRET = "jwtsecretdemo";
    private static final String ISS = "quant";

    // 角色的key
    private static final String PERMISSIONURL_METHOD = "permissionurl_method";

    // 过期时间是3600秒，既是1个小时
    public static final int EXPIRATION = 60 * 60 * 24 * 7;

    // 选择了记住我之后的过期时间为7天
    private static final long EXPIRATION_REMEMBER = 604800L;

    // 创建token
    public static String createToken(String username, List permissionurl_method, boolean isRememberMe) {
        long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PERMISSIONURL_METHOD, permissionurl_method);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setClaims(map)
                .setIssuer(ISS)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .compact();
    }

    // 从token中获取用户名
    public static String getUsername(String token) throws AdminLoginTokenException {
        return getTokenBody(token).getSubject();
    }

    // 获取用户角色
    public static List getUserRole(String token) throws AdminLoginTokenException {
        return (List) getTokenBody(token).get(PERMISSIONURL_METHOD);
    }

    // 是否已过期
    public static boolean isExpiration(String token) {
        try {
            return getTokenBody(token).getExpiration().before(new Date());
        } catch (Exception e) {
            logger.error("isExpiration {}", e.getMessage(), e);
            return true;
        }
    }

    private static Claims getTokenBody(String token) throws AdminLoginTokenException {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace("Bearer", ""))
                    .getBody();
        } catch (ExpiredJwtException e) {
            logger.error("Token已过期: {} " + e);
            throw new AdminLoginTokenException("Token已过期");
        } catch (UnsupportedJwtException e) {
            logger.error("Token格式错误: {} " + e);
            throw new AdminLoginTokenException("Token格式错误");
        } catch (MalformedJwtException e) {
            logger.error("Token没有被正确构造: {} " + e);
            throw new AdminLoginTokenException("Token没有被正确构造");
        } catch (SignatureException e) {
            logger.error("签名失败: {} " + e);
            throw new AdminLoginTokenException("签名失败");
        } catch (IllegalArgumentException e) {
            logger.error("非法参数异常: {} " + e);
            throw new AdminLoginTokenException("非法参数异常");
        }

    }
}
